!// Dmitry.Konovalov@jcu.edu.au Dmitry.A.Konovalov@gmail.com, 2013

module jm_conf_mod;
use vec_mod;
implicit none;
private;

! NOTE 12-Apr-2013: name any new public functions as conf_xxx()
public CONF_T, CONF_SHELL_T, CONF_H_MTRX, test_jm_conf_mod &
&, conf_arr_dbg, conf_arr_init, conf_dbg, conf_init;

integer, parameter :: MAX_SHELL_N = 2;

type CONF_H_MTRX;
  real(DP), pointer :: hm(:,:); ! hmatrix
end type

type CONF_SHELL_T;
  real(DP), pointer :: rwf(:); ! radial wave function
  real(DP), pointer :: drv(:); ! its first derivative
  integer :: L;
  ! 
endtype

type CONF_T; sequence;
  !totLL(j) - total coupled L's up to and including j'th shell
  integer :: totLL(MAX_SHELL_N); ! config's total L is totLL(maxi)
  ! NOTE: totLL(1) == sh(1)%LL;  
  ! NOTE: totSS(1) == sh(1)%SS;  
  
  !totSS(j) - total coupled spins up to and including j'th shell 
  integer :: totSS(MAX_SHELL_N); !  config's spin is totSS(maxi)
  
!  type(CONF_SHELL_T) :: sh(MAX_SHELL_N);  ! array of shells
   integer :: idN(MAX_SHELL_N);  ! absolute (unique) one-electron shell id
   integer :: idL(MAX_SHELL_N); ! shell's one-electron L
   integer :: q(MAX_SHELL_N);  ! number of electrons in the shell
   integer :: LL(MAX_SHELL_N); ! shell's total L 
   integer :: SS(MAX_SHELL_N); ! shell's total spin; stored as spin*2
  
  integer :: maxi;  !number of shells in this config; mini=1
  ! if needed any other coupling order could be added here    
end type;

!type(CONF_SHELL_T), parameter :: CONF_SHELL_INIT = CONF_SHELL_T(-1,-2,-3,-4,-5,-6,-7,-8); ! count numbers for debugging/testing

contains;!=====================================================================

subroutine test_jm_conf_mod();
  character(LEN=64) :: name = "test_jm_conf_mod";
  call dbg_in(name); 
  !call test_atom_conf_e1();
  !call test_atom_conf_e2();  
  call dbg_out(name); 
end subroutine


SUBROUTINE conf_dbg(conf, showAll);    
  type(CONF_T), intent(IN) :: conf;
  logical, intent(IN), optional :: showAll;
  character(len=1024) :: strHelp;
  integer i, maxs; 
  if (present(showAll) .AND. showAll) then
    maxs = UBOUND(conf%totLL, 1);
    call dbg_int("UBOUND(conf%totLL, 1)=", maxs);
    call dbg_int("conf%maxi=", conf%maxi);
    call veci_dbg("conf%totLL=", conf%totLL);
    call veci_dbg("conf%totSS=", conf%totSS);
    call veci_dbg("conf%idN=", conf%idN);
    call veci_dbg("conf%idL=", conf%idL);
    call veci_dbg("conf%q=", conf%q);
    call veci_dbg("conf%LL=", conf%LL);
    call veci_dbg("conf%SS=", conf%SS);
  else
    maxs = conf%maxi; 
  endif
  do i = 1, maxs
    write(strHelp, *) &
    & "maxi=", TRIM(int_to_str(conf%maxi)) & 
    &, ", sh(", TRIM(int_to_str(i)) &
    &, ", idN=", TRIM(int_to_str(conf%idN(i))) &
    &, ", idL=", TRIM(int_to_str(conf%idL(i))) &
    &, ", q=", TRIM(int_to_str(conf%q(i))) &
    &, ", LL=", TRIM(int_to_str(conf%LL(i))) &
    &, ", SS=", TRIM(int_to_str(conf%SS(i))) &
    &, ", totLL=", TRIM(int_to_str(conf%totLL(i))) &
    &, ", totSS=", TRIM(int_to_str(conf%totSS(i))) &
    &, ")="
    call dbg_str(TRIM(strHelp));
  enddo
end subroutine

SUBROUTINE conf_init(conf);    
  type(CONF_T), intent(OUT) :: conf;
  character(LEN=64) :: name = "conf_init";
  !call dbg_in(name);
  conf%maxi = -1;
  conf%totLL = -1;
  conf%totSS = -1;
  conf%idN = -1;
  conf%idL = -1;
  conf%q = -1;
  conf%LL = -1;
  conf%SS = -1;
  !call dbg_out(name);
end subroutine

SUBROUTINE conf_arr_dbg(confArr);    
  type(CONF_T), intent(IN) :: confArr(:);
  integer i; 
  do i = 1, UBOUND(confArr, 1);
    call dbg_int("confArr(i=", i);
    call conf_dbg(confArr(i));
  enddo
end subroutine

SUBROUTINE conf_arr_init(confArr);    
  type(CONF_T), intent(OUT) :: confArr(:);
  character(LEN=64) :: name = "conf_arr_init";
  integer i, mini, maxi; 
  call dbg_in(name);
  mini = LBOUND(confArr, 1);
  maxi = UBOUND(confArr, 1);  !call dbg_int("UBOUND(confArr, 1)=", maxi);
  do i = mini, maxi;
    !call dbg_int("confArr(i=", i);
    call conf_init(confArr(i));
    !call conf_dbg(confArr(i), .TRUE.);
  enddo
  !call dbg_out(name);
end subroutine



end module